/**
 * *********************************************************************
 * FILENAME:
 *    rpc_client.c
 *
 * DESCRIPTION:
 *    rpc client
 *
 * AUTHOR:
 *    Tsihang
 *
 * CHANGE HISTORY:
 *    <date>        <author>    <desc>
 *    2012.08.16    Tsihang   create this file
 *
 * *********************************************************************
 */ 
#include "rpcGloableTables.h"
#include "rpc_client.h"
#include "socket_list.h"
#include "rpc_system_info.h"

int 	CPU_TICK_PER_SEC = 1000;
int  	MaxCcNum;
//store all of the ips
char g_cc_ipaddr_list[MAX_CC_NUM][32];
int 	init_flag;

void SetDefalutTick()
{
	CPU_TICK_PER_SEC = 0;
}


void cc_ipaddr_list_init()
{
    int i;

    for( i = 0; i < MAX_CC_NUM; i++ )
    {
        g_cc_ipaddr_list[i][0] = 0;
    }
}

int get_cc_ipaddr_list()
{
    int sock_fd;
    int num = 0;
    struct ifreq ifr_ip;
	struct   sockaddr_in *sin;  

    if ((sock_fd=socket(AF_INET, SOCK_STREAM, 0)) == -1)  
    {  
         printf("socket create failse...GetLocalIp!/n");  
         return (-1);  
    }  
	
    memset(&ifr_ip, 0, sizeof(ifr_ip));  
    strncpy(ifr_ip.ifr_name, DEVICE_OF_NETWORK, sizeof(ifr_ip.ifr_name) - 1); 
    if( ioctl( sock_fd, SIOCGIFADDR, &ifr_ip) < 0 )     
    {    
    	  printf("Can not get IP of %s, using loop address\n", DEVICE_OF_NETWORK);
    	  strcpy(g_cc_ipaddr_list[0], "127.0.0.1");
	  num += 1;
	  close(sock_fd);
         return (num);     
    }  

    sin = (struct sockaddr_in *)&ifr_ip.ifr_addr;
    strcpy(g_cc_ipaddr_list[0], inet_ntoa(sin->sin_addr));
    printf("local ip:%s /n",g_cc_ipaddr_list[0]);    
    close(sock_fd);
    num += 1;
    return num;
}

void cli_rpc_parse_param(unsigned char *response, int *offset, unsigned char *result)
{
    RPC_PARAM_CLIENT_ST *pParam = (RPC_PARAM_CLIENT_ST *)(response + *offset);

    /*printf("\r\n type = %u length = %u value = %u \r\n",
        pParam->type, pParam->length, *((unsigned int *)pParam->value));*/

    memcpy(result, pParam->value, pParam->length-4);

    *offset += pParam->length;
}

void cli_rpc_generate_head(unsigned char *request, int pkt_len, int rpc_id, int param_num)
{
    RPC_HEAD_CLIENT_ST *pHead = (RPC_HEAD_CLIENT_ST *)request;

    pHead->version = 1;
    pHead->pkt_type = RPC_REQUEST;
    pHead->pkt_len = pkt_len;
    pHead->resv = 0;
    pHead->rpc_id = rpc_id;
    pHead->param_num = param_num;
}

void cli_rpc_generate_param(unsigned char *request, int *offset, int *pkt_len, int type, int len, unsigned char *value)
{
    RPC_PARAM_CLIENT_ST *pParam = (RPC_PARAM_CLIENT_ST *)(request + *offset);

    pParam->type = type;
    pParam->length = len;
    memcpy(pParam->value, value, len-4);

    *offset += len;
    *pkt_len += len;
}

int cli_rpc_get_pkt_len(unsigned char *packet)
{
    RPC_HEAD_CLIENT_ST *pHead = (RPC_HEAD_CLIENT_ST*)packet;

	if(pHead->version!=1 || pHead->pkt_type != RPC_RESPONSE)
	{
		printf("\r\n packet version error or type error\n");
	}

    return pHead->pkt_len;
}

int cli_rpc_get_param_num(unsigned char *packet)
{
	RPC_HEAD_CLIENT_ST *pHead = (RPC_HEAD_CLIENT_ST *)packet;

	return pHead->param_num;
}

int readCCResponse(int fd,unsigned char *response)
{
	int nbytes, pkt_len, offset = 0;
    	unsigned char buf[RPC_REQUEST_LNGTH];
    	int first_flag = 1;

	while (1)
	{
		/* Read raw data from socket */
		nbytes = read(fd, buf, RPC_REQUEST_LNGTH-1);
		if (nbytes <= 0)
		{	
			printf("\r\n nbytes = %d \r\n",nbytes);
			return -1;
		 }
		/* length field of packet is in the first packet */
		if (first_flag == 1)
		{
			pkt_len = cli_rpc_get_pkt_len(buf);
			if (pkt_len > RPC_REQUEST_LNGTH-1)
			{
				printf("\r\n cli packet length is too long \r\n");
			}
			first_flag = 0;
		}
		memcpy(response+offset,buf,nbytes);
		if (nbytes+offset != pkt_len)
		{
			offset += nbytes;
			continue;
		}
		else
		{
			memset(buf, 0, sizeof(buf));
			break;
		}
	}
	return pkt_len;
}

int cliRpcWrite(int sockfd,char *data , int len)
{
	int wl=0,resend = 0;
	//else
	{
		if (sockfd < 0)
		{
			printf("<rpcWrite> sockfd error\r\n");
			return -1;
		}
		if (len > 0)
		{
			wl = write(sockfd, data, len);
			resend =0;
			while ((wl != len) && (resend<5))
			{
				printf("resend : w1=%d,len =%d\r\n",wl,len);
				taskDelay(2);
				if(wl < 0)
					wl =0;
				wl += write(sockfd, &data[wl], len-wl);
				resend++;
			}
			if(wl!=len)
			{
				close (sockfd);
				printf("send error : w1=%d,len =%d\r\n",wl,len);
			}
			/*printf("cli SmisServSubmit write %d bytes\r\n",wl);*/
		}
	}
	int ifor = 0;
	printf("cli <CLIGetSysInfo> request rspLen =%d,request = ",len);
		for(ifor=0;ifor<len;ifor++)
			printf("0x%02x ",data[ifor]);
		printf("\r\n");
	return 0;
}


int main(void)
{	
	int retvalue = 0;
	
	SetDefalutTick();		//Not use now
	//init ipaddr table
	cc_ipaddr_list_init();
	if((MaxCcNum=get_cc_ipaddr_list()) == 0)
       	return 0;
	//printf("ip: %s\n", g_cc_ipaddr_list[0]);
	taskDelay(CPU_TICK_PER_SEC*30);

/* init ssl */
	ssl_low_level_init();

	socketListInit();
	while(1){
		retvalue = CLIGetSysInfo();
		retvalue = CLIGetSysInfo_IP();
		printf("func = %s  line:%d return value = %d \n", __FUNCTION__, __LINE__, retvalue);
		sleep(2);
	}
	return 0;
}
